package com.example.springpostbody.core.filter;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.example.springpostbody.core.CustomRequestWrapper;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.ContentCachingRequestWrapper;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


// Filter和HandlerInterceptor 参考https://juejin.cn/post/7368255086289633330
//@Component
//@Order(Ordered.HIGHEST_PRECEDENCE)
//@WebFilter(urlPatterns = "/*", filterName = "customFilter")
public class CustomFilter extends OncePerRequestFilter {

    private final AntPathMatcher pathMatcher = new AntPathMatcher();

    // 允许列表
    private final List<String> validPaths = List.of("/user/add", "/user/update", "/order/add", "/test/post");
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        // 请求到达控制器之后才能这样读取
        /*ContentCachingRequestWrapper wrappedRequest1 = new ContentCachingRequestWrapper(request);
        String requestBody = new String(wrappedRequest1.getContentAsByteArray());
        System.out.println("requestBody="+requestBody);*/

        // 获取请求头
        Enumeration<String> headerNames = request.getHeaderNames();
        Map<String, String> headers = new HashMap<>();
        // 遍历所有请求头，并存入Map中
        while (headerNames.hasMoreElements()) {
            String headerName = headerNames.nextElement();
            String headerValue = request.getHeader(headerName);
            headers.put(headerName, headerValue);
        }
        System.out.println("请求头"+JSON.toJSONString(headers));

        // 获取请求的字符编码
        Charset charset = request.getCharacterEncoding() != null ? Charset.forName(request.getCharacterEncoding()):Charset.defaultCharset();

        // 获取请求url
        String requestPath = request.getRequestURI();
        /*boolean isValidPath = pathMatcher.match("/user/add", requestPath) ||
                pathMatcher.match("/user/update", requestPath) ||
                pathMatcher.match("/order/add", requestPath);*/
        // 判断是不是在规定的url中间
        boolean isValidPath = validPaths.stream().anyMatch(path -> pathMatcher.match(path, requestPath));
        if ("POST".equalsIgnoreCase(request.getMethod()) && "application/json".equals(request.getContentType()) && isValidPath) {

            // 通过自定义的包装请求对象
            CustomRequestWrapper wrappedRequest = new CustomRequestWrapper(request);
            // 获取原始请求体
            String originalBody = wrappedRequest.getBody();
            System.out.println("CustomFilter --> 自定义的RequestWrapper获取报文信息= " + originalBody);
            if(JSON.isValid(originalBody)){
                ObjectMapper mapper = new ObjectMapper();
                try {
                    JSONObject jsonObject = JSONObject.parse(originalBody);
                    System.out.println("CustomFilter --> 转换成json对象="+jsonObject.toJSONString());
                    JsonNode jsonNode = mapper.readTree(originalBody);
                    //return true;
                } catch (Exception e) {
                    //return false;
                    e.printStackTrace();
                    response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                    response.setContentType("application/json");
                    response.setCharacterEncoding("UTF-8");
                    response.getWriter().write("{\"msg\": \"Json数据包含非法字符\"}");
                    return;
                }
            }else {
                response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                response.setContentType("application/json");
                response.setCharacterEncoding("UTF-8");
                response.getWriter().write("{\"msg\": \"不是有效的Json数据\"}");
                return;
            }

            // 如果需要修改请求体（比如：替换某个字段）
            String modifiedBody = originalBody.replace("lisi", "李四修改成王五");

            // 如果请求体需要修改，我们只需要在原有的wrapper中直接替换请求体内容
            if (!modifiedBody.equals(originalBody)) {
                // 更新缓存的字节数组，避免重新封装 InputStream
                //String encoding = request.getCharacterEncoding() != null ? request.getCharacterEncoding() : StandardCharsets.UTF_8.name();
                /*if(Objects.nonNull(request.getCharacterEncoding())){
                    charset = Charset.forName(request.getCharacterEncoding());
                }*/
                wrappedRequest = new CustomRequestWrapper(request) {
                    @Override
                    public ServletInputStream getInputStream() throws IOException {
                        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(modifiedBody.getBytes(charset));
                        return getServletInputStream(byteArrayInputStream);
                    }
                };
            }
            // 继续传递请求对象
            filterChain.doFilter(wrappedRequest, response);
        } else {
            filterChain.doFilter(request, response); // 继续处理请求
        }


    }
}
